package com.suredy.app.porject.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.suredy.app.porject.constants.FlowStatus;
import com.suredy.app.porject.model.Bid;
import com.suredy.app.porject.model.FlowOfBid2User;
import com.suredy.core.service.BaseSrvWithEntity;
import com.suredy.security.entity.UserEntity;

@Service
public class FlowOfBid2UserSrv extends BaseSrvWithEntity<FlowOfBid2User> {

	@Autowired
	private BidSrv bidSrv;

	@Override
	public DetachedCriteria getDc(FlowOfBid2User t) {
		DetachedCriteria dc = super.getDc(t);

		if (t == null)
			return dc;

		if (!StringUtils.isBlank(t.getId())) {
			dc.add(Restrictions.eq("id", t.getId()));
		}
		if (t.getBid() != null) {
			dc.add(Restrictions.eq("bid", t.getBid()));
		}
		if (t.getUser() != null) {
			dc.add(Restrictions.eq("user", t.getUser()));
		}
		if (t.getStatus() != null) {
			dc.add(Restrictions.eq("status", t.getStatus()));
		}
		if (t.getActive() != null) {
			dc.add(Restrictions.eq("active", t.getStatus()));
		}

		return dc;
	}

	@Transactional
	public boolean sendWithUsers(String bidId, String[] userIds, FlowStatus status) {
		if (StringUtils.isBlank(bidId))
			return false;

		if (userIds == null || userIds.length <= 0)
			return false;

		if (status == null)
			return false;

		Bid b = this.bidSrv.get(bidId);

		if (b == null || StringUtils.isBlank(b.getId()))
			return false;

		// 将所有的流程用户置为非活动用户
		FlowOfBid2User search = new FlowOfBid2User();
		search.setBid(b);
		List<FlowOfBid2User> olds = this.readByEntity(search);
		if (olds != null) {
			for (FlowOfBid2User old : olds) {
				old.setActive(false);
				this.update(old);
			}
		}

		// 新建或者更新流程用户
		for (String uid : userIds) {
			FlowOfBid2User flow = new FlowOfBid2User();

			flow.setBid(b);
			flow.setUser(new UserEntity(uid));
			flow.setStatus(status);

			// 唯一
			FlowOfBid2User exists = this.readSingleByEntity(flow);

			if (exists != null)
				flow = exists;

			flow.setActive(true);
			flow.setTime(new Date());

			this.saveOrUpdate(flow);
		}

		// 更新最新状态（系统不允许状态位并行）
		b.setFlowStatus(status);
		this.bidSrv.update(b);

		return true;
	}

	@Transactional
	public boolean changeStatus(String bidId, FlowStatus status) {
		if (StringUtils.isBlank(bidId))
			return false;

		if (status == null)
			return false;

		Bid b = this.bidSrv.get(bidId);

		if (b == null || StringUtils.isBlank(b.getId()))
			return false;

		// 将所有的流程用户置为非活动用户
		FlowOfBid2User search = new FlowOfBid2User();
		search.setBid(b);
		List<FlowOfBid2User> olds = this.readByEntity(search);
		if (olds != null) {
			for (FlowOfBid2User old : olds) {
				old.setActive(false);
				this.update(old);
			}
		}

		// 新建或者更新流程用户
		FlowOfBid2User flow = new FlowOfBid2User();
		flow.setBid(b);
		flow.setStatus(status);

		// 唯一
		FlowOfBid2User exists = this.readSingleByEntity(flow);

		if (exists != null)
			flow = exists;

		flow.setActive(true);
		flow.setTime(new Date());

		this.saveOrUpdate(flow);

		// 更新最新状态（系统不允许状态位并行）
		b.setFlowStatus(status);
		this.bidSrv.update(b);

		return true;
	}

	@SuppressWarnings("unchecked")
	public List<Bid> getAllBidOf(DetachedCriteria bidDc, String[] userIds, Boolean active, FlowStatus... status) {
		// Bid查询对象
		DetachedCriteria dc = bidDc == null ? this.bidSrv.getDc(null) : bidDc;
		dc.addOrder(Order.asc("projectNo"));

		boolean hasChildSearch = false;

		// 子查询对象
		DetachedCriteria child = this.getDc(null);
		child.setProjection(Property.forName("bid.id"));

		if (userIds != null && userIds.length > 0) {
			List<UserEntity> userParam = new ArrayList<UserEntity>();

			for (String id : userIds) {
				if (StringUtils.isBlank(id))
					continue;

				userParam.add(new UserEntity(id));
			}

			if (!userParam.isEmpty()) {
				child.add(Restrictions.in("user", userParam));
				hasChildSearch = true;
			}
		}

		if (active != null) {
			child.add(Restrictions.eq("active", active));
			hasChildSearch = true;
		}

		if (status != null && status.length > 0) {
			List<FlowStatus> statusParam = new ArrayList<FlowStatus>();

			for (FlowStatus s : status) {
				if (s == null)
					continue;

				statusParam.add(s);
			}

			if (!statusParam.isEmpty()) {
				child.add(Restrictions.in("status", statusParam));
				hasChildSearch = true;
			}
		}

		if (hasChildSearch)
			dc.add(Property.forName("id").in(child));

		return (List<Bid>) this.bidSrv.readByCriteria(dc);
	}

	@SuppressWarnings("unchecked")
	public List<Bid> getBidOf(DetachedCriteria bidDc, String[] userIds, Boolean active, int page, int pageSize, FlowStatus... status) {
		// Bid查询对象
		DetachedCriteria dc = bidDc == null ? this.bidSrv.getDc(null) : bidDc;
		dc.addOrder(Order.asc("projectNo"));

		boolean hasChildSearch = false;

		// 子查询对象
		DetachedCriteria child = this.getDc(null);
		child.setProjection(Property.forName("bid.id"));

		if (userIds != null && userIds.length > 0) {
			List<UserEntity> userParam = new ArrayList<UserEntity>();

			for (String id : userIds) {
				if (StringUtils.isBlank(id))
					continue;

				userParam.add(new UserEntity(id));
			}

			if (!userParam.isEmpty()) {
				child.add(Restrictions.in("user", userParam));
				hasChildSearch = true;
			}
		}

		if (active != null) {
			child.add(Restrictions.eq("active", active));
			hasChildSearch = true;
		}

		if (status != null && status.length > 0) {
			List<FlowStatus> statusParam = new ArrayList<FlowStatus>();

			for (FlowStatus s : status) {
				if (s == null)
					continue;

				statusParam.add(s);
			}

			if (!statusParam.isEmpty()) {
				child.add(Restrictions.in("status", statusParam));
				hasChildSearch = true;
			}
		}

		if (hasChildSearch)
			dc.add(Property.forName("id").in(child));

		return (List<Bid>) this.bidSrv.readByCriteria(dc, page, pageSize);
	}

	public int getBidCountOf(DetachedCriteria bidDc, String[] userIds, Boolean active, FlowStatus... status) {
		// Bid查询对象
		DetachedCriteria dc = bidDc == null ? this.bidSrv.getDc(null) : bidDc;
		dc.addOrder(Order.asc("projectNo"));

		boolean hasChildSearch = false;

		// 子查询对象
		DetachedCriteria child = this.getDc(null);
		child.setProjection(Property.forName("bid.id"));

		if (userIds != null && userIds.length > 0) {
			List<UserEntity> userParam = new ArrayList<UserEntity>();

			for (String id : userIds) {
				if (StringUtils.isBlank(id))
					continue;

				userParam.add(new UserEntity(id));
			}

			if (!userParam.isEmpty()) {
				child.add(Restrictions.in("user", userParam));
				hasChildSearch = true;
			}
		}

		if (active != null) {
			child.add(Restrictions.eq("active", active));
			hasChildSearch = true;
		}

		if (status != null && status.length > 0) {
			List<FlowStatus> statusParam = new ArrayList<FlowStatus>();

			for (FlowStatus s : status) {
				if (s == null)
					continue;

				statusParam.add(s);
			}

			if (!statusParam.isEmpty()) {
				child.add(Restrictions.in("status", statusParam));
				hasChildSearch = true;
			}
		}

		if (hasChildSearch)
			dc.add(Property.forName("id").in(child));

		return this.bidSrv.getCountByCriteria(dc);
	}

}
